﻿#ifndef QBCICORE_H
#define QBCICORE_H

#include <QHash>
#include <QObject>

#include "qbciconfig.h"
#include "qbciglobal.h"

#include <QCoreApplication>

namespace bci {
class QBci;

class QBciMod : public QObject {
  Q_OBJECT

  friend class QBci;

public:
  /**
   * @brief Construct a new QBciMod object
   *
   * @param id The id of QBciMod must be different
   * from each other.
   *
   * @note Although QBciMod is derived from QObject,
   * it will NEVER have a parent QObject. If QBciMod
   * have been added to QBci, its lifecycle will be
   * managed by QBci. Otherwise, you should delete
   * QBciMod manually.
   */
  QBciMod(const QString &id);
  QBciMod() = delete;
  QBciMod(const QBciMod &) = delete;
  QBciMod(QBciMod &&) = delete;
  virtual ~QBciMod(){};

  /**
   * @brief get id of module
   *
   * @return QString
   */
  QString id() const { return this->objectName(); };
  /**
   * @brief return if the module is running.
   */
  bool isRunning() const { return isRunningFlag; }

public slots:
  /*!
   * \brief 模块可以从cxt里更新参数
   */
  virtual void updateConfig(const ::bci::QBciConfig *){};

private:
  bool isRunningFlag = false;
  QBciContext *cxt = nullptr;

signals:
  /**
   * @brief after start() executed, execute this fun
   *
   * @param id
   */
  void started(const QString &id);
  /**
   * @brief after stop() executed, execute this fun
   *
   * @param id
   */
  void stopped(const QString &id);

protected slots:
  virtual void protectedStartSlot(::bci::QBciContext *cxt);
  virtual void protectedStopSlot();

  /**
   * @brief after module receive start signal execute
   * before emit started signal
   */
  virtual void beforeStart() {}
  /**
   * @brief after emit started signal
   *
   * @note CANNOT use cxt in afterStart()
   */
  virtual void afterStart() {}
  /**
   * @brief after module receive stop signal execute
   * before emit stopped signal
   */
  virtual void beforeStop() {}
  /**
   * @brief after emit started signal
   *
   * @note CANNOT use cxt in afterStop()
   */
  virtual void afterStop() {}

  /**
   * @brief print error mesg by logger
   *
   * @param mesg message
   * @note only print while cxt is not null.
   */
  void error(const QString &mesg);
  /**
   * @brief print warn mesg by logger
   *
   * @param mesg message
   * @note only print while cxt is not null.
   */
  void warn(const QString &mesg);
  /**
   * @brief print info mesg by logger
   *
   * @param mesg message
   * @note only print while cxt is not null.
   */
  void info(const QString &mesg);
  /**
   * @brief print debug mesg by logger
   *
   * @param mesg message
   * @note only print while cxt is not null.
   */
  void debug(const QString &mesg);

protected:
  QBci *bci = nullptr;
  QThread *bciThread = nullptr;
};

} // namespace bci

#endif